#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :my_st_comps.py
# @Time      :2024/10/29 18:56
# @Author    :zhou_yi

"""
    自己封装的streamlit组件
"""

import streamlit as st


def st_markdown_center_text(text):
    # 标题
    st.markdown(
        f"""
        <h2 style='text-align: center; color: #FF6347;'>{text}</h2>
        """,
        unsafe_allow_html=True
    )


# 表格的样式
def st_markdown_table_style():
    return st.markdown("""
                <style>
                    /* 设置表格的通用样式 */
                    table, th, td {
                        border: 1px solid black; /* 设置表格的边框为1px实线和黑色 */
                        border-collapse: collapse; /* 边框合并为单一边框 */
                        font_size:40px;
                    }
            
                    /* 为th设置特定的样式 */
                    th {
                        height: 80px; /* 设置表头单元格的高度 */
                        text-align: left; /* 设置文字对齐方式 */
                        padding: 15px; /* 设置内边距 */
                    }
            
                    /* 为td设置特定的样式 */
                    td {
                        width:150px;
                        padding: 20px; /* 设置内边距 */
                    }
                </style>
                
                """, unsafe_allow_html=True)


# 点位信息表格
def st_markdown_point_info(data):
    return st.markdown(f""" <table align="center">
                        <h5 align="center">生活源有害垃圾点位信息</h5>
                        <tr>
                            <th>管辖单位</th>
                            <td>{data['part']}</td>
                            <th>区域名称</th>
                            <td>{data['name']}</td>
                        </tr>
                        <tr>
                            <th>点位编号</th>
                            <td>{data['_id']}</td>
                            <th>点位名称/桶编号</th>
                            <td>{data['point']}/{data['code']}</td>
                        </tr>
                        <tr>
                            <th>地理位置</th>
                            <td colspan=3>{data['address']}</td>
                        </tr>
                        <tr>
                            <th>清运方联系人</th>
                            <td></td>
                            <th>联系方式</th>
                            <td></td>
                        </tr>
                        <tr>
                            <th>管理方联系人</th>
                            <td>{data['manager']}</td>
                            <th>联系方式</th>
                            <td>{data['tel']}</td>
                        </tr>
                        <tr>
                            <th>经度</th>
                            <td>{data['long']}</td>
                            <th>纬度</th>
                            <td>{data['lat']}</td>
                        </tr>
                        <tr>
                            <th>注意事项</th>
                            <td colspan=3>{data['notice']}</td>
                        </tr>
                    </table>
                
                
                """, unsafe_allow_html=True)


# 清运记录表格
def st_markdown_clear_waster_record(data):
    return st.markdown(f"""<table align="center">
                            <h5 align="center">生活源有害垃圾清运记录单</h5>
                             <tr>
                                <th>日期</th>
                                <td>{data['date']}</td>
                                <th>时间</th>
                                <td>{data['time']}</td>
                            </tr>
                            <tr>
                                <th>管理方签字</th>
                                <td></td>
                                <th>清运方签字</th>
                                <td></td>
                            </tr>
                            <tr>
                                <th>废电池类</th>
                                <td>{data['w1']}</td>
                                <th>废杀虫剂、消毒剂</th>
                                <td>{data['w5']}</td>
                            </tr>
                            <tr>
                                <th>废荧光灯管类</th>
                                <td>{data['w2']}</td>
                                <th>废胶片及废相纸</th>
                                <td>{data['w6']}</td>
                            </tr>
                            <tr>
                                <th>废药品类</th>
                                <td>{data['w3']}</td>
                                <th>溶剂及其包装物</th>
                                <td>{data['w7']}</td>
                            </tr>
                            <tr>
                                <th>过期化妆品</th>
                                <td>{data['w4']}</td>
                                <th>废油漆、硒鼓墨盒</th>
                                <td>{data['w8']}</td>
                            </tr>
                            <tr>
                                <th>合计</th>
                                <td colspan=3>{data['w_total']}</td>
                            </tr>
                        </table>
                        """, unsafe_allow_html=True)


# 给键值对字典（一一对应），选择键返回值
def st_select_box_dic_opt(label: str, options: dict, index: int | None = 0, key=None, help_=None, on_change=None,
                          args=None, kwargs=None, *, placeholder: str = "Choose an option", disabled: bool = False,
                          label_visibility="visible"):
    """
        选择器,给的选项是字典,选择键,输出值 字典的键值一定要一一对应
    :param help_:
    :param label_visibility:
    :param disabled:
    :param placeholder:
    :param kwargs:
    :param args:
    :param on_change:
    :param index:
    :param label:
    :param options: 
    :param key: 
    :return: 
    """
    options = {v: k for k, v in options.items()}  # 字典键值互转
    selection = st.selectbox(label=label, index=index, key=key,
                             options=list(options.keys()),  # 选择器输出的内容
                             format_func=lambda k: options[k],  # 在选项框中看到的内容
                             help=help_, on_change=on_change, args=args, kwargs=kwargs, placeholder=placeholder,
                             disabled=disabled, label_visibility=label_visibility)
    return selection


# 创建文件并下载文件到本地
def st_download_file(btn_label, *, fn, options: dict, download_filename: str):
    """
        创建文件并下载文件到本地
    :param btn_label: 按钮标签名称
    :param fn: 函数->在server端生成文件,return 文件的地址
    :param options: fn的参数
    :param download_filename: 下载到本地文件的名称
    :return:
    """
    col1, col2 = st.columns(2)
    with col1:
        btn = st.button(btn_label, key=btn_label)

    if btn:
        st.code(f"{download_filename}")
        res = fn(**options)  # 在服务器上生成文件并返回文件地址
        if res:
            # 从服务器上读取刚生成的文件
            with open(res, 'rb') as _f:
                _bin = _f.read()

            with col2:
                try:
                    st.download_button(label="点击下载",
                                       data=_bin,
                                       file_name=download_filename,
                                       )
                except:
                    st.error('下载文件发生错误....')
                    st.stop()

        else:
            st.error('生成文件发生错误....')
            st.stop()


# 上传文件
def st_upload_file():
    # 文件上传
    uploaded_file = st.file_uploader("请选择文件进行上传", type=None)

    # 检查是否有文件上传
    if uploaded_file is not None:
        # 显示文件信息
        st.write(f"文件名: {uploaded_file.name}")
        st.write(f"文件大小: {uploaded_file.size} 字节")

        # 获取文件字节内容
        file_bytes = uploaded_file.read()

        # 将文件保存到本地
        save_path = f"./{uploaded_file.name}"
        with open(save_path, "wb") as f:
            f.write(file_bytes)

        st.success(f"文件已保存到: {save_path}")


# 分块上传
def st_upload_file_by_chuck(label: str = "请上传文件", type_=None, label_visibility='visible',
                            save_name: str = None, save_path: str = None, chuck: int = 1024):
    # 文件上传
    uploaded_file = st.file_uploader(label=label, type=type_, label_visibility=label_visibility)

    # 检查是否有文件上传
    if uploaded_file is not None:
        # 设定保存路径
        if save_name is None:
            save_name = uploaded_file.name

        if save_path is None:
            save_path = f"./{save_name}"

        # 显示进度条
        progress_bar = st.progress(0)

        # 初始化
        bytes_written = 0  # 已写入的字节数

        # 打开文件并分块写入本地文件
        with open(save_path, "wb") as f:
            while True:
                file_chunk = uploaded_file.read(chuck)  # 建立文件块：按块读取数据

                if not file_chunk:
                    break  # 读取完成

                f.write(file_chunk)  # 将文件块写入到本地文件
                bytes_written += len(file_chunk)  # 字节数递增

                # 更新进度条
                _percent = bytes_written / uploaded_file.size
                progress_bar.progress(_percent)

        progress_bar.empty()

        return save_path
